package repository

import (
	"errors"

	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/model"
	"gorm.io/gorm"
)

// UserRepository 定义用户仓库接口
// 这个接口定义了所有用户数据操作的方法

type UserRepository interface {
	// 创建新用户
	Create(user *model.User) error
	// 根据ID获取用户
	GetByID(id int64) (*model.User, error)
	// 根据用户名获取用户
	GetByUsername(username string) (*model.User, error)
	// 更新用户信息
	Update(user *model.User) error
	// 删除用户
	Delete(id int64) error
}

// userRepository 实现UserRepository接口
// 这个结构体封装了与数据库交互的逻辑

type userRepository struct {
	db *gorm.DB
}

// NewUserRepository 创建一个新的用户仓库实例
// 参数db是gorm.DB对象，用于与数据库交互
func NewUserRepository(db *gorm.DB) UserRepository {
	return &userRepository{db: db}
}

// Create 创建新用户
// 参数user是用户对象指针，包含要创建的用户信息
func (r *userRepository) Create(user *model.User) error {
	// 使用gorm的Create方法将用户数据插入数据库
	if err := r.db.Create(user).Error; err != nil {
		return err
	}
	return nil
}

// GetByID 根据ID获取用户
// 参数id是用户的唯一标识
// 返回用户对象指针和可能的错误
func (r *userRepository) GetByID(id int64) (*model.User, error) {
	var user model.User
	// 使用gorm的First方法根据主键查询用户
	if err := r.db.First(&user, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil // 用户不存在返回nil，而不是错误
		}
		return nil, err
	}
	return &user, nil
}

// GetByUsername 根据用户名获取用户
// 参数username是用户的用户名
// 返回用户对象指针和可能的错误
func (r *userRepository) GetByUsername(username string) (*model.User, error) {
	var user model.User
	// 使用gorm的Where和First方法根据用户名查询用户
	if err := r.db.Where("username = ?", username).First(&user).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil // 用户不存在返回nil，而不是错误
		}
		return nil, err
	}
	return &user, nil
}

// Update 更新用户信息
// 参数user是包含更新后信息的用户对象指针
func (r *userRepository) Update(user *model.User) error {
	// 使用gorm的Save方法更新用户数据
	if err := r.db.Save(user).Error; err != nil {
		return err
	}
	return nil
}

// Delete 删除用户
// 参数id是要删除的用户ID
func (r *userRepository) Delete(id int64) error {
	// 使用gorm的Delete方法删除用户
	if err := r.db.Delete(&model.User{}, id).Error; err != nil {
		return err
	}
	return nil
}